﻿using System;

namespace Quail
{
    /// <summary>
    /// Extensions for IQuailControl objects
    /// </summary>
    public static class QuailControlExtensions
    {
        /// <summary>
        /// waits for a condition to occur
        /// </summary>
        /// <param name="control"></param>
        /// <param name="description">description of the wait condition</param>
        /// <param name="predicate">function that returns true when the wait condition has occurred</param>
        public static void WaitFor(this IQuailControl control, string description, Func<bool> predicate)
        {
            new WaitParameters("WaitFor")
                {
                    Delegate = predicate,
                    FailMessage = "TimedOut: " + description,
                    PollingInterval = 200
                }
                .Wait(control.ActiveTask);
        }

        /// <summary>
        /// Waits for the control to exist until the Browser's default timeout.
        /// </summary>
        /// <exception cref="WebBrowserException">Thrown if the control is not found within the default timeout</exception>
        public static void WaitExists(this IQuailControl control)
        {
            control.WaitExists("Control " + control.Selector + " does not exist");
        }

        /// <summary>
        /// Waits for the control to exist until the Browser's default timeout.
        /// </summary>
        /// <param name="control">The quail control</param>
        /// <param name="failmessage">The message to display when the control does not Exist</param>
        /// <exception cref="WebBrowserException">Thrown if the control is not found within the default timeout</exception>
        public static void WaitExists(this IQuailControl control, string failmessage)
        {
            new WaitParameters("WaitExists")
                {
                    Delegate = () => control.Exists,
                    FailMessage = failmessage,
                    PollingInterval = 200
                }
                .Wait(control.ActiveTask);
        }

        /// <summary>
        /// Waits for the control to be enabled until the Browser's default timeout.
        /// </summary>
        /// <exception cref="WebBrowserException">Thrown if the control is not enabled within the default timeout</exception>
        public static void WaitEnabled(this IQuailControl control)
        {
            control.WaitEnabled("Control " + control.Selector + " is not enabled");
        }

        /// <summary>
        /// Waits for the control to be enabled until the Browser's default timeout.
        /// </summary>
        /// <param name="control">The quail control</param>
        /// <param name="failmessage">The message to display when the control does not become enabled</param>
        /// <exception cref="WebBrowserException">Thrown if the control is not enabled within the default timeout</exception>
        public static void WaitEnabled(this IQuailControl control, string failmessage)
        {
            new WaitParameters("WaitEnabled")
                {
                    Delegate = () => control.Enabled,
                    FailMessage = failmessage,
                    PollingInterval = 200
                }
                .Wait(control.ActiveTask);
        }

        /// <summary>
        /// Waits for the control to be visible until the Browser's default timeout.
        /// </summary>
        /// <exception cref="WebBrowserException">Thrown if the control is not visible within the default timeout</exception>
        public static void WaitVisible(this IQuailControl control)
        {
            control.WaitVisible("Control " + control.Selector + " did not become visible");
        }

        /// <summary>
        /// Waits for the control to be visible until the Browser's default timeout.
        /// </summary>
        /// <param name="control">The quail control</param>
        /// <param name="failmessage">The message to display when the control does not become visible</param>
        /// <exception cref="WebBrowserException">Thrown if the control is not visible within the default timeout</exception>
        public static void WaitVisible(this IQuailControl control, string failmessage)
        {
            new WaitParameters("WaitVisible")
                {
                    Delegate = () => control.Visible,
                    FailMessage = failmessage,
                    PollingInterval = 200
                }
                .Wait(control.ActiveTask);
        }

        /// <summary>
        /// Waits for the control to hide until the Browser's default timeout.
        /// </summary>
        /// <exception cref="WebBrowserException">Thrown if the control is not visible within the default timeout</exception>
        public static void WaitHidden(this IQuailControl control)
        {
            WaitHidden(control, "Control " + control.Selector + " did not become hidden");
        }


        /// <summary>
        /// Waits for the control to hide until the Browser's default timeout.
        /// </summary>
        /// <param name="control">The quail control</param>
        /// <param name="failmessage">The message to display when the control does not become hidden</param>
        /// <exception cref="WebBrowserException">Thrown if the control is not visible within the default timeout</exception>
        public static void WaitHidden(this IQuailControl control, string failmessage)
        {
            new WaitParameters("WaitHidden")
                {
                    Delegate = () => !control.Visible,
                    FailMessage = failmessage,
                    PollingInterval = 200
                }
                .Wait(control.ActiveTask);
        }

        /// <summary>
        /// Waits for the control to exist using the Browser's default timeout.
        /// </summary>
        /// <returns>True if the control becomes visible within the timeout</returns>
        public static bool DidControlBecomeVisible(this IQuailControl control)
        {
            return control.DidControlBecomeVisible("Control " + control.Selector + " does not become visible");
        }

        /// <summary>
        /// Waits for the control to exist using the Browser's default timeout.
        /// </summary>
        /// <param name="control">The quail control</param>
        /// <param name="failmessage">The message to display when the control does not become visible</param>
        /// <returns>True if the control becomes visible within the timeout</returns>
        public static bool DidControlBecomeVisible(this IQuailControl control, string failmessage)
        {
            return
                new WaitParameters("WaitVisible")
                    {
                        Delegate = () => control.Visible,
                        FailMessage = failmessage,
                        PollingInterval = 200,
                        FailStatus = LogStatus.Information,
                        ThrowOnStatusFailTimeout = false
                    }
                    .Wait(control.ActiveTask);
        }
    }
}
